﻿(function ($) {
    $.fn.mUnionSelect = function (options) {
        var selectPrefix = 'mUS_' + (new Date().valueOf()) + '_';
        var defaults = {
            selectedValues: [],
            urls: [],
            params: [],
            level: 1,
            isMultlple: false,
            selectedMax: 5,
            inputName: '',
            items: [],
            title: '请选择',
        };

        var $this = $(this);
        var id = $(this).attr('id');
        var options = $.extend(defaults, options);
        var timeStamp = new Date().getMilliseconds() + "_" + id;
        var popId = 'mUnionSelect_' + timeStamp;
        var listId = 'list_' + timeStamp;
        var itemClass = 'item_' + timeStamp;
        var showItemClass = 'seletedItem_' + timeStamp;
        var removeItemClass = 'removeItem_' + timeStamp;
        var selectedClass = 'select';
        var selectedItemsListId = 'showItems_' + timeStamp;
        var confirmId = 'confirm_' + timeStamp;
        var backId = 'back_' + timeStamp;
        var inputId = 'input_' + timeStamp;
        var clickId = 'click_' + timeStamp;
        var backup = [];
        /* <(backId)  title    ok(comfirmId)
         * <itemRootId>
         * items(itemId)
         * <>
         */

        function renderBaseElement(popId, listId, title, inputId, confirmId, backId) {
            var html = '' +
            '<div id="' + popId + '" style="display:none;width:100%;background:#fff" >' +
                '<select ' + (options.isMultlple ? 'multiple' : '') + ' name="' + options.inputName + '" id="' + inputId + '" style="display:none"></select>' +
                '<div style="padding-top: 10px;display: -moz-box; display: -webkit-box;display: box;z-index: 999; position: fixed; width: 100%;background: #fff">' +
                    '<a id="' + backId + '" class="point" style="display: block;text-align: left;color: #999;margin-left: 15px;"><i class="iconfont ml5 icon-left"></i></a>' +
                    '<span style="display: block;-webkit-box-flex: 3;-moz-box-flex: 3;box-flex: 3;font-size: 16px;text-align: center;">' + title + '</span>' +
                    '<a class="orange fs16 mr15 point" id="' + confirmId + '" style="display: block;text-align: left;color: #999;margin-left: 15px;">完成</a>' +
                '</div>' +
                '<ul id="' + listId + '" style="margin-top: 45px; padding: 0 20px;" class="changesList">' +
                '</ul>' +
            '</div>';
            return html;
        }

        function renderSelectedItemsElement(clickId, selectedItemsListId) {
            return '<a class="point" id="' + clickId + '">' +
                        '<p id="' + selectedItemsListId + '">' +
                            '<i class="iconfont icon-right fr"></i>' +
                        '</p>' +
                    '</a>';
        }

        $this.before(renderSelectedItemsElement(clickId, selectedItemsListId)).hide();
        var form = $this.closest('form');
        if(form.length == 0){
            form = $(body);
        }
        form.append(renderBaseElement(popId, listId, options.title, inputId, confirmId, backId));
        var $selectedItems = $('#' + selectedItemsListId);
        var $pop = $('#' + popId);
        var $select = $('#' + inputId);
        var $itemsList = $('#' + listId);

        var currentLevel = 1;

        // 判断是否被选定
        function isSelected(value) {
            for (var i = 0, len = options.selectedValues.length; i < len; i++) {
                if (value === options.selectedValues[i].Value) {
                    return true;
                }
            }
            return false;
        }

        // 渲染单个元素
        function renderItem(option) {
            return '<li data-value="' + option.Value +
                '" title="' +
                option.Text +
                '"  class="sec01 ' + itemClass + (isSelected(option.Value) ? ' ' + selectedClass : '') +
                '" style="cursor: pointer;line-height: 55px;border-bottom: 1px solid #eee;color: #494949;font-size: 16px;padding-left: 10px;"><span>' + option.Text + '</span></li>'
        }

        //输出列表,返回的json是[{Text:"xxx",Value:"xxx"},...]
        function renderItems(items) {
            var html = '';
            for (var i = 0, len = items.length; i < len; i++) {
                html += renderItem(items[i])
            }
            return html;
        }

        // 渲染被选定
        function renderSelectedItem(option) {
            return '<span style="width: auto;font-size: 14px;">' + option.Text + '</span>';
        }

        // 渲染已选定的
        function setSelectedItems() {
            var html = '';
            for (var i = 0, len = options.selectedValues.length; i < len; i++) {
                html += renderSelectedItem(options.selectedValues[i]);
            }
            $selectedItems.html(html + '<i class="iconfont icon-right fr"></i>');
        }

        // 设置值
        function setSelectedValues() {
            var optionsHtml = '';
            for (var i = 0, len = options.selectedValues.length; i < len; i++) {
                optionsHtml += '<option value="' + options.selectedValues[i].Value + '" selected></option>';
            }
            $select.html(optionsHtml);
        }

        function done() {
            setSelectedItems();
            setSelectedValues();
            $pop.removeClass('shcool_pos').fadeOut(300);
        }

        // 取消
        function doCancel() {
            options.selectedValues = backup;
            done();
        }

        // 备份
        function doBackup() {
            backup = [];
            for (var i = 0, len = options.selectedValues.length; i < len; i++) {
                backup.push(options.selectedValues[i]);
            }
        }

        // 获取每一级的配置
        function getConfigs(level, urls, paramNames) {
            var root, parent, child, option;
            var paramName = typeof (paramNames) == 'string'
                ? paramNames
                : typeof (paramNames) == 'object' && !paramNames.length? 'parentId' : null;
            var url = typeof (urls) == 'string' ? urls : null;
            var configs = [];

            for (var i = 1; i <= level; i++) {
                config = {
                    url: url ? url : urls[i],
                    urlParamName: paramName ? paramName : paramNames[i],
                    level: i,
                    urlParamValue: null,
                };
                configs.push(config);
            }

            return configs;
        }

        // 删除元素
        function removeItem(value) {
            for (var i = 0, len = options.selectedValues.length; i < len; i++) {
                item = options.selectedValues[i];
                if (item.Value == value) {
                    options.selectedValues.splice(i, 1);
                    return;
                }
            }
        }

        // 添加元素
        function addItem(text, value) {
            if (!options.isMultlple) {
                options.selectedValues = [];
            }
            options.selectedValues.push({
                Text: text,
                Value: value
            });
        }

        // 切换元素状态（是否选定）
        function switchItem(selector) {
            if (selector.hasClass(selectedClass)) {
                selectedClass.removeClass(selectedClass);
                removeItem(selector.data('value'));
            } else {
                if (options.isMultlple) {
                    if (options.selectedValues.length >= options.selectedMax) {
                        alert('最多只能选取' + options.selectedMax + '个');
                        return;
                    }
                } else {
                    $('.' + itemClass).removeClass(selectedClass);
                }
                selector.addClass(selectedClass);
                addItem(selector.attr('title'), selector.data('value'));
                if (!options.isMultlple) { // 单选的话，直接完成
                    done();
                }
            }
        }

        // 根据父级id获取元素
        function getItems(parentValue) {
            var item, items = [];
            for (var i = 0, len = options.items.length; i < len; i++) {
                item = options.items[i];
                if ((!item.ParentValue && !parentValue) || (item.ParentValue === parentValue)) {
                    items.push(item);
                }
            }
            return items;
        }

        var configs = getConfigs(options.level, options.urls, options.params);

        // 缓存元素
        function appendItems(items, parentValue) {
            var item;
            for (var i = 0, len = items.length; i < len; i++) {
                item = items[i];
                if (!item.ParentValue) {
                    item.ParentValue = parentValue;
                }
                options.items.push(item);
            }
        }

        // 加载数据
        function loadItems() {
            var params = {}, items = [];
            var config = configs[currentLevel-1];
            var parentValue = !!config.urlParamValue ? config.urlParamValue : null;

            if (config.urlParamName) {
                params[config.urlParamName] = parentValue;
            }

            $itemsList.html('<li class="sec01" style="cursor: pointer;line-height: 55px;border-bottom: 1px solid #eee;color: #494949;font-size: 16px;padding-left: 10px;"><span>加载中ing...</span></li>');

            var handlerItems = function (items) {
                if (!items || !items.length) {
                    items = [];
                }
                $itemsList.html(renderItems(items));
            }

            var ajaxHandlerItems = function (items) {
                handlerItems(items);
                appendItems(items, parentValue); // 加载数据本地缓存
            }

            items = getItems(parentValue); // 读取缓存
            if (items.length) {
                handlerItems(items);
            } else {
                $.post(config.url, params, ajaxHandlerItems);
            }
        }

        // 元素点击
        function itemClick(selector) {
            if (currentLevel == options.level) {
                switchItem(selector);
            } else {
                configs[currentLevel++].urlParamValue = selector.data('value');
                loadItems();
            }
        }

        // 元素点击
        $(document).on('click', '.' + itemClass, function () {
            itemClick($(this));
        });

        function init() {
            currentLevel = 1;
            setSelectedValues();
        }

        init();

        $('#' + clickId).click(function () {
            currentLevel = 1;
            doBackup();
            $pop.addClass('shcool_pos').fadeIn(300);
            loadItems();
        });

        $('#' + confirmId).click(function () {
            done();
        });

        $('#' + backId).click(function () {
            if (currentLevel == 1) {
                doCancel();
            } else {
                currentLevel--;
                loadItems();
            }
        });
    };
})(jQuery);